
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI算力计算器</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        .card-gradient {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .input-highlight {
            box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.5);
        }
    </style>
</head>
<body class="bg-gray-100 min-h-screen">
    <div class="container mx-auto px-4 py-8 max-w-4xl">
        <div class="card-gradient text-white rounded-xl p-6 mb-8 shadow-lg">
            <h1 class="text-3xl font-bold mb-2"><i class="fas fa-calculator mr-2"></i>AI算力计算器</h1>
            <p class="opacity-90">支持多种计算精度的算力卡性能计算工具</p>
        </div>

        <div class="bg-white rounded-xl shadow-md p-6 mb-8">
            <div class="grid md:grid-cols-2 gap-6">
                <!-- 配置区 -->
                <div>
                    <h2 class="text-xl font-semibold mb-4 text-gray-800 border-b pb-2">
                        <i class="fas fa-microchip mr-2 text-purple-600"></i>算力卡配置
                    </h2>
                    
                    <div class="mb-4">
                        <label class="block text-gray-700 mb-2">厂商</label>
                        <select id="vendor" class="w-full p-3 border rounded-lg focus:input-highlight">
                            <option value="nvidia">NVIDIA</option>
                            <option value="amd">AMD</option>
                            <option value="ascend">昇腾</option>
                        </select>
                    </div>

                    <div class="mb-4">
                        <label class="block text-gray-700 mb-2">型号</label>
                        <select id="model" class="w-full p-3 border rounded-lg focus:input-highlight">
                            <!-- NVIDIA选项 -->
                            <option value="h100" data-tflops-fp16="756" data-tflops-fp32="60" data-tflops-fp64="30" data-tflops-int8="1512" data-tflops-int4="3024" data-memory="80">NVIDIA H100</option>
                            <option value="a100" data-tflops-fp16="624" data-tflops-fp32="19.5" data-tflops-fp64="9.7" data-tflops-int8="1248" data-tflops-int4="2496" data-memory="80">NVIDIA A100</option>
                            <option value="h800" data-tflops-fp16="450" data-tflops-fp32="45" data-tflops-fp64="22.5" data-tflops-int8="900" data-tflops-int4="1800" data-memory="80">NVIDIA H800</option>
                            <option value="l20" data-tflops-fp16="144" data-tflops-fp32="72" data-tflops-fp64="0" data-tflops-int8="288" data-tflops-int4="576" data-memory="48">NVIDIA L20</option>
                            <option value="4090" data-tflops-fp16="82.6" data-tflops-fp32="82.6" data-tflops-fp64="1.3" data-tflops-int8="165.2" data-tflops-int4="330.4" data-memory="24">NVIDIA RTX 4090</option>
                            
                            <!-- AMD选项 -->
                            <option value="mi300x" class="amd-option" data-tflops-fp16="1530" data-tflops-fp32="765" data-tflops-fp64="38" data-tflops-int8="3060" data-tflops-int4="6120" data-memory="192">AMD MI300X</option>
                            <option value="mi250x" class="amd-option" data-tflops-fp16="383" data-tflops-fp32="191" data-tflops-fp64="95" data-tflops-int8="766" data-tflops-int4="1532" data-memory="128">AMD MI250X</option>
                            
                            <!-- 昇腾选项 -->
                            <option value="910b" class="ascend-option" data-tflops-fp16="256" data-tflops-fp32="128" data-tflops-fp64="64" data-tflops-int8="512" data-tflops-int4="1024" data-memory="32">昇腾910B</option>
                            <option value="910b4" class="ascend-option" data-tflops-fp16="384" data-tflops-fp32="192" data-tflops-fp64="96" data-tflops-int8="768" data-tflops-int4="1536" data-memory="64">昇腾910B4</option>
                        </select>
                    </div>

                    <div class="mb-4">
                        <label class="block text-gray-700 mb-2">计算精度</label>
                        <select id="precision" class="w-full p-3 border rounded-lg focus:input-highlight">
                            <option value="fp16">FP16/半精度</option>
                            <option value="fp32">FP32/单精度</option>
                            <option value="fp64">FP64/双精度</option>
                            <option value="int8">INT8/8位整数</option>
                            <option value="int4">INT4/4位整数</option>
                        </select>
                    </div>

                    <div class="mb-4">
                        <label class="block text-gray-700 mb-2">数量</label>
                        <input type="number" id="quantity" min="1" value="1" 
                               class="w-full p-3 border rounded-lg focus:input-highlight">
                    </div>

                    <button id="calculate" 
                            class="w-full bg-purple-600 hover:bg-purple-700 text-white py-3 px-4 rounded-lg font-medium transition duration-200">
                        <i class="fas fa-calculator mr-2"></i>计算总算力
                    </button>
                </div>

                <!-- 结果区 -->
                <div>
                    <h2 class="text-xl font-semibold mb-4 text-gray-800 border-b pb-2">
                        <i class="fas fa-chart-bar mr-2 text-purple-600"></i>计算结果
                    </h2>
                    
                    <div class="bg-gray-50 p-4 rounded-lg mb-4">
                        <div class="flex justify-between mb-2">
                            <span class="text-gray-600">单卡算力:</span>
                            <span id="single-tflops" class="font-bold">0 TFLOPS</span>
                        </div>
                        <div class="flex justify-between mb-2">
                            <span class="text-gray-600">计算精度:</span>
                            <span id="precision-type" class="font-bold">FP16</span>
                        </div>
                        <div class="flex justify-between mb-2">
                            <span class="text-gray-600">显存容量:</span>
                            <span id="memory-size" class="font-bold">0 GB</span>
                        </div>
                        <div class="flex justify-between mb-2">
                            <span class="text-gray-600">卡数量:</span>
                            <span id="card-count" class="font-bold">0</span>
                        </div>
                        <div class="border-t my-2"></div>
                        <div class="flex justify-between text-lg mt-3">
                            <span class="text-gray-700 font-medium">总算力:</span>
                            <span id="total-tflops" class="text-2xl font-bold text-purple-600">0 TFLOPS</span>
                        </div>
                        <div class="flex justify-between text-lg mt-2">
                            <span class="text-gray-700 font-medium">总显存:</span>
                            <span id="total-memory" class="text-2xl font-bold text-blue-600">0 GB</span>
                        </div>
                    </div>

                    <div class="bg-blue-50 p-4 rounded-lg border border-blue-200">
                        <h3 class="font-medium text-blue-800 mb-2">
                            <i class="fas fa-info-circle mr-1"></i>算力等级参考
                        </h3>
                        <ul class="text-sm text-gray-700 space-y-1">
                            <li><span class="font-medium">1P</span> (PetaFLOP/s): 1,000 TFLOPS</li>
                            <li><span class="font-medium">10P</span>: 10,000 TFLOPS</li>
                            <li><span class="font-medium">100P</span>: 100,000 TFLOPS</li>
                        </ul>
                        <div class="mt-3 text-sm">
                            <p id="peta-scale" class="font-medium text-blue-700">当前配置 ≈ <span class="text-lg">0P</span></p>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 历史记录 -->
        <div class="bg-white rounded-xl shadow-md p-6">
            <h2 class="text-xl font-semibold mb-4 text-gray-800 border-b pb-2">
                <i class="fas fa-history mr-2 text-purple-600"></i>计算历史
            </h2>
            <div id="history" class="space-y-2 max-h-60 overflow-y-auto">
                <!-- 历史记录将在这里动态生成 -->
            </div>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const vendorSelect = document.getElementById('vendor');
            const modelSelect = document.getElementById('model');
            const precisionSelect = document.getElementById('precision');
            const quantityInput = document.getElementById('quantity');
            const calculateBtn = document.getElementById('calculate');
            const singleTflopsEl = document.getElementById('single-tflops');
            const precisionTypeEl = document.getElementById('precision-type');
            const memorySizeEl = document.getElementById('memory-size');
            const cardCountEl = document.getElementById('card-count');
            const totalTflopsEl = document.getElementById('total-tflops');
            const totalMemoryEl = document.getElementById('total-memory');
            const petaScaleEl = document.getElementById('peta-scale');
            const historyEl = document.getElementById('history');
            
            let history = JSON.parse(localStorage.getItem('tflopsHistory')) || [];

            // 厂商切换逻辑
            vendorSelect.addEventListener('change', function() {
                const vendor = this.value;
                const options = modelSelect.querySelectorAll('option');
                
                options.forEach(option => {
                    if (option.classList.contains(vendor + '-option') || 
                        (vendor === 'nvidia' && !option.classList.contains('amd-option') && !option.classList.contains('ascend-option'))) {
                        option.style.display = 'block';
                    } else {
                        option.style.display = 'none';
                    }
                });
                
                const visibleOptions = Array.from(options).filter(opt => opt.style.display !== 'none');
                if (visibleOptions.length > 0) {
                    modelSelect.value = visibleOptions[0].value;
                    updateModelInfo();
                }
            });

            // 更新单卡信息
            function updateModelInfo() {
                const selectedOption = modelSelect.options[modelSelect.selectedIndex];
                const precision = precisionSelect.value;
                const tflops = selectedOption.getAttribute('data-tflops-' + precision) || 'N/A';
                const memory = selectedOption.getAttribute('data-memory');
                
                singleTflopsEl.textContent = tflops === 'N/A' ? '不支持' : tflops + ' TFLOPS';
                precisionTypeEl.textContent = precision.toUpperCase();
                memorySizeEl.textContent = memory + ' GB';
            }
            
            modelSelect.addEventListener('change', updateModelInfo);
            precisionSelect.addEventListener('change', updateModelInfo);
            updateModelInfo();

            // 计算按钮逻辑
            calculateBtn.addEventListener('click', function() {
                const quantity = parseInt(quantityInput.value) || 1;
                const precision = precisionSelect.value;
                const selectedOption = modelSelect.options[modelSelect.selectedIndex];
                const singleTflops = parseFloat(selectedOption.getAttribute('data-tflops-' + precision));
                const singleMemory = parseInt(selectedOption.getAttribute('data-memory'));
                
                if (isNaN(singleTflops)) {
                    alert('当前选择的精度类型不支持该型号显卡');
                    return;
                }
                
                const totalTflops = singleTflops * quantity;
                const totalMemory = singleMemory * quantity;
                const petaScale = (totalTflops / 1000).toFixed(3);
                
                cardCountEl.textContent = quantity;
                precisionTypeEl.textContent = precision.toUpperCase();
                totalTflopsEl.textContent = totalTflops.toFixed(1) + ' TFLOPS';
                totalMemoryEl.textContent = totalMemory + ' GB';
                petaScaleEl.innerHTML = `当前配置 ≈ <span class="text-lg">${petaScale}P</span>`;
                
                // 历史记录
                const historyItem = {
                    date: new Date().toLocaleString(),
                    vendor: vendorSelect.value,
                    model: modelSelect.options[modelSelect.selectedIndex].text.split('(')[0].trim(),
                    precision: precision.toUpperCase(),
                    quantity: quantity,
                    tflops: totalTflops.toFixed(1),
                    memory: totalMemory
                };
                
                history.unshift(historyItem);
                if (history.length > 5) history.pop();
                localStorage.setItem('tflopsHistory', JSON.stringify(history));
                updateHistory();
            });

            // 更新历史记录
            function updateHistory() {
                historyEl.innerHTML = '';
                
                history.forEach(item => {
                    const historyItem = document.createElement('div');
                    historyItem.className = 'bg-gray-50 p-3 rounded-lg border border-gray-200';
                    historyItem.innerHTML = `
                        <div class="flex justify-between">
                            <span class="font-medium">${item.model} × ${item.quantity}</span>
                            <span class="text-purple-600 font-bold">${item.tflops} TFLOPS</span>
                        </div>
                        <div class="flex justify-between text-xs text-gray-500 mt-1">
                            <span>${item.precision} | ${item.memory}GB</span>
                            <span>${item.date}</span>
                        </div>
                    `;
                    historyEl.appendChild(historyItem);
                });
            }
            
            updateHistory();
        });
    </script>
</body>
</html>
